package mt.filter;

import static org.junit.Assert.*;

import mt.Order;
import mt.comm.ServerSideMessage;
import mt.comm.ServerSideMessage.Type;
import mt.dummy.ServerCommDummy;
import mt.filter.clock.DummyClock;

import org.junit.Before;
import org.junit.Test;

/**
 * Test battery for blacklisting with a controlled clock.
 * @author tmspo@iscte-iul.pt
 *
 */
public class AnalyticsFilterBlacklistDummyTest {
	/**
	 * This unit test initialises an AnalyticsFilter which receives a DummyClock
	 * and a ServerCommDummy as parameters. The DummyClock allows control over
	 * the ticking.
	 */
	DummyClock clock = new DummyClock();
	ServerCommDummy serverComm = new ServerCommDummy();
	AnalyticsFilter analyticsFilter = new AnalyticsFilter(serverComm, clock);
	
	/**
	 * Fills a ServerComm ServerSideMessage with 6 messages that contain the same
	 * type, same SenderNickname and same order.
	 */
	@Before
	public void setUpFilter(){
		for(int i = 0; i < 6; i++){
			serverComm.getListOfMessages().add(new ServerSideMessage() {
				
				@Override
				public Type getType() {
					return Type.NEW_ORDER;
				}
				
				@Override
				public String getSenderNickname() {
					return "batata";
				}
				
				@Override
				public Order getOrder() {
					return Order.createBuyOrder(null, null, 0, 0);
				}
			});
		}
	}

	/**
	 * Tests if a user gets blacklisted by sending 4 messages in 12 ticks.
	 * The expected output is that the AnalyticsFilter returns the exceeding
	 * message with its Type unchanged.
	 */
	@Test
	public void testDummyClockNotBlacklisting() {
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		Type originalType = serverComm.getListOfMessages().peek().getType();
		assertEquals(originalType, analyticsFilter.getNextMessage().getType());
	}
	
	/**
	 * Tests if a user gets blacklisted by sending 4 messages in 9 ticks.
	 * The expected output is that the AnalyticsFilter changes the exceeding
	 * message with its Type changed to Type.DISCONNECTED.
	 */
	@Test
	public void testDummyClockBlacklisting() {
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		assertEquals(Type.DISCONNECTED, analyticsFilter.getNextMessage().getType());
	}
	
	/**
	 * Tests is a user gets disconnected by sending a message while he is still
	 * in the blacklist.
	 * The expected output is that the AnalyticsFilter returns the exceeding
	 * message with its Type changed to Type.DISCONNECTED.
	 */
	@Test
	public void testDummyClockBlacklisted() {
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 3; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
				for(int i = 0; i < 3; i++){
			clock.incrementTick();
			System.out.println(i);
		}
		assertEquals(Type.DISCONNECTED, analyticsFilter.getNextMessage().getType());
		
		for(int i = 0; i < 32; i++){
			clock.incrementTick();
		}
		Type originalType = serverComm.getListOfMessages().peek().getType();
		assertEquals(originalType, analyticsFilter.getNextMessage().getType());
	}
	
	/**
	 * Tests is a user gets disconnected by sending a message while he already
	 * got out of the blacklist.
	 * The expected output is that the AnalyticsFilter returns the exceeding
	 * message with its Type unchanged.
	 */
	@Test
	public void testDummyClockNotBlacklisted() {
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		for(int i = 0; i < 4; i++){
			clock.incrementTick();
		}
		analyticsFilter.getNextMessage();
		
		for(int i = 0; i < 19; i++){
			clock.incrementTick();
		}
		Type originalType = serverComm.getListOfMessages().peek().getType();
		assertEquals(originalType, analyticsFilter.getNextMessage().getType());
	}

}
